package com.xu.sso.db.service.impl;

import com.xu.sso.core.enums.AppTypeEnum;
import com.xu.sso.core.enums.StatusEnum;
import com.xu.sso.core.model.AppPathRole;
import com.xu.sso.db.dao.AppExMapper;
import com.xu.sso.db.dao.AppRoleExMapper;
import com.xu.sso.db.dao.AppUserExMapper;
import com.xu.sso.db.model.AppResourcesRole;
import com.xu.sso.db.model.base.App;
import com.xu.sso.db.model.base.AppExample;
import com.xu.sso.db.model.base.AppUser;
import com.xu.sso.db.model.base.AppUserExample;
import com.xu.sso.db.service.AppDBService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AppDBServiceImpl implements AppDBService {

    @Autowired
    private AppExMapper appExMapper;
    @Autowired
    private AppRoleExMapper appRoleExMapper;
    @Autowired
    private AppUserExMapper appUserExMapper;

    @Override
    public List<AppPathRole> findAppPermissions(String appId) {
        List<AppResourcesRole> list = appRoleExMapper.selectAppResourcesRoles(appId);
        List<AppPathRole> appRoles = new ArrayList<>();
        AppResourcesRole oldRole = null;
        Set<String> roles = null;
        for (int i = 0; i < list.size(); i++) {
            AppResourcesRole resRole = list.get(i);
            if (null != resRole.getRoleId()) {
                String roleName = appRoleExMapper.selectRoleName(resRole.getRoleId());
                if (StringUtils.isNotBlank(roleName)) {
                    resRole.setRole(roleName);
                }
            }
            if (null == oldRole) {
                roles = new HashSet<>();
                if (StringUtils.isNotBlank(resRole.getRole())) {
                    roles.add(resRole.getRole());
                }
            } else if (oldRole.getPath().equals(resRole.getPath())) {
                if (StringUtils.isNotBlank(resRole.getRole())) {
                    roles.add(resRole.getRole());
                }
            } else {
                AppPathRole appPathRole = new AppPathRole();
                appPathRole.setLogin(Boolean.valueOf(oldRole.getLogin()));
                appPathRole.setPath(oldRole.getPath());
                appPathRole.setRoles(roles);
                appRoles.add(appPathRole);
                roles = new HashSet<>();
                if (StringUtils.isNotBlank(resRole.getRole())) {
                    roles.add(resRole.getRole());
                }
            }
            if (i == (list.size() - 1)) {
                AppPathRole appPathRole = new AppPathRole();
                appPathRole.setLogin(Boolean.valueOf(resRole.getLogin()));
                appPathRole.setPath(resRole.getPath());
                appPathRole.setRoles(roles);
                appRoles.add(appPathRole);
            }
            oldRole = resRole;
        }
        return appRoles;

    }

    @Override
    public App findAppById(Integer id) {
        return appExMapper.selectByPrimaryKey(id);
    }

    @Override
    public App findAppByAppId(String appId) {
        AppExample example = new AppExample();
        example.createCriteria().andAppIdEqualTo(appId);
        List<App> apps = appExMapper.selectByExample(example);
        if (null != apps && apps.size() > 0) {
            return apps.get(0);
        }
        return null;
    }

    @Override
    public List<App> findAllApps() {
        return appExMapper.selectByExample(new AppExample());
    }

    @Override
    public List<App> findAllStartWebApp() {
        AppExample example = new AppExample();
        example.createCriteria().andAppTypeEqualTo(AppTypeEnum.web.getCode()).andStatusEqualTo(StatusEnum.Start.getCode());
        return appExMapper.selectByExample(example);
    }

    @Override
    public List<App> findAllServerApp() {
        AppExample example = new AppExample();
        example.createCriteria().andAppTypeEqualTo(AppTypeEnum.server.getCode());
        return appExMapper.selectByExample(example);
    }

    @Override
    public List<App> findAllStartApps() {
        AppExample example = new AppExample();
        example.createCriteria().andStatusEqualTo(StatusEnum.Start.getCode());
        return appExMapper.selectByExample(example);
    }

    @Override
    public List<App> findAllUserApps(String username) {
        return appExMapper.selectAllAppsByUser(username);
    }

    @Override
    public List<App> findAllAppByLeader(String username) {
        AppExample example = new AppExample();
        example.createCriteria().andLeaderLike("%" + username + "%");
        return appExMapper.selectByExample(example);
    }

    @Override
    public List<App> findApps(App app) {
        if (null == app) {
            return null;
        }
        AppExample example = new AppExample();
        AppExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(app.getAppId())) {
            criteria.andAppIdLike("%" + app.getAppId() + "%");
        }
        if (StringUtils.isNotBlank(app.getStatus())) {
            criteria.andStatusEqualTo(app.getStatus());
        }
        if (StringUtils.isNotBlank(app.getAppName())) {
            criteria.andAppNameLike("%" + app.getAppName() + "%");
        }
        if (StringUtils.isNotBlank(app.getLeader())) {
            criteria.andLeaderLike("%" + app.getLeader() + "%");
        }
        return appExMapper.selectByExample(example);
    }

    @Override
    public int createApp(App app) {
        app.setCreateTime(new Date());
        app.setUpdateTime(new Date());
        return appExMapper.insertSelective(app);
    }

    @Override
    public int updateApp(App app) {
        app.setUpdateTime(new Date());
        return appExMapper.updateByPrimaryKeySelective(app);
    }

    @Override
    public int deleteApp(String appId) {
        AppExample example = new AppExample();
        example.createCriteria().andAppIdEqualTo(appId);
        return appExMapper.deleteByExample(example);
    }

    @Override
    public boolean checkAppExist(String appId) {
        AppExample example = new AppExample();
        example.createCriteria().andAppIdEqualTo(appId);
        List<App> apps = appExMapper.selectByExample(example);
        if (null != apps && apps.size() > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean checkAppLeader(String appId, String username) {
        AppExample example = new AppExample();
        example.createCriteria().andAppIdEqualTo(appId);
        List<App> apps = appExMapper.selectByExample(example);
        if (null != apps && apps.size() > 0) {
            App app = apps.get(0);
            String[] leaders = app.getLeader().split(",");
            long count = Arrays.stream(leaders).filter(l -> l.equals(username)).count();
            if (count > 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int changeStatus(String appId, String status) {
        AppExample example = new AppExample();
        example.createCriteria().andAppIdEqualTo(appId);
        App app = new App();
        app.setStatus(status);
        app.setUpdateTime(new Date());
        return appExMapper.updateByExampleSelective(app, example);
    }

    @Override
    public int createAppUser(String appId, String username) {
        AppUser appUser = new AppUser();
        appUser.setAppId(appId);
        appUser.setUsername(username);
        appUser.setCreateTime(new Date());
        appUser.setUpdateTime(new Date());
        return appUserExMapper.insertSelective(appUser);
    }

    @Override
    public int createAppUserList(String appId, List<String> usernames) {
        return appUserExMapper.installAppUserList(usernames, appId);
    }

    @Override
    public int deleteAllAppUserByApp(String appId) {
        AppUserExample example = new AppUserExample();
        example.createCriteria().andAppIdEqualTo(appId);
        return appUserExMapper.deleteByExample(example);
    }

    @Override
    public int deleteAllAppUserByUser(String username) {
        AppUserExample example = new AppUserExample();
        example.createCriteria().andUsernameEqualTo(username);
        return appUserExMapper.deleteByExample(example);
    }

    @Override
    public int deleteAppUser(String username, String appId) {
        AppUserExample example = new AppUserExample();
        example.createCriteria().andAppIdEqualTo(appId).andUsernameEqualTo(username);
        return appUserExMapper.deleteByExample(example);
    }

    @Override
    public boolean checkAppPowerByUser(String appId, String username) {
        AppUserExample example = new AppUserExample();
        example.createCriteria().andAppIdEqualTo(appId).andUsernameEqualTo(username);
        List<AppUser> appUsers = appUserExMapper.selectByExample(example);
        if (null != appUsers && appUsers.size() > 0) {
            return true;
        }
        return false;
    }

}
